home *** CD-ROM | disk | FTP | other *** search
- #define LIBQDISPLAY_CORE
- #include "../include/libqdisplay.h"
-
- /*
- * Render a Quake polygon:
- * read it from the db
- * transform it into 3d
- * clip it in 3d
- * compute the 2d texture gradients
- * scan convert
- * pass off the spans
- */
-
- /* drawing */
- displaypointer texture;
- int textureRow;
- int textureMask1, textureMask2;
- short int textureShift1, textureShift2;
- short int textureMip;
- short int textureType;
- unsigned char textureColor;
-
- #ifndef __OPTIMIZE__
- #include "draw-orig.c"
- #else
- #include "draw-opti.c"
- #endif
-
- static inline void draw_poly(int n, point_3d ** vl)
- {
- int i, j, y, ey;
- fix ymin, ymax;
-
- /* find max and min y height */
- ymin = ymax = vl[0]->sy;
- for (i = 1; i < n; ++i) {
- if (vl[i]->sy < ymin)
- ymin = vl[i]->sy;
- else if (vl[i]->sy > ymax)
- ymax = vl[i]->sy;
- }
-
- /* scan out each edge */
- j = n - 1;
- for (i = 0; i < n; ++i) {
- scan_convert(vl[i], vl[j]);
- j = i;
- }
-
- y = FIX_INT(ymin);
- ey = FIX_INT(ymax);
-
- #ifndef __OPTIMIZE__
- for (; y < ey; y++) {
- int sx = FIX_INT(scan[y][0]);
- int ex = FIX_INT(scan[y][1]);
-
- if (ex - sx) {
- /* iterate over all spans and draw */
- #ifdef DRIVER_8BIT
- if (localDim.frameDepth <= 8) {
- if (displayType == DISPLAY_TEXTURED)
- draw_spans8(y, sx, ex);
- else if (displayType == DISPLAY_FLAT)
- draw_spans8flat(y, sx, ex);
- else if (displayType == DISPLAY_WIRE)
- draw_spans8wire(y, sx, ex);
- }
- else
- #endif
- #ifdef DRIVER_16BIT
- if (localDim.frameDepth <= 16)
- draw_spans16(y, sx, ex);
- else
- #endif
- #ifdef DRIVER_24BIT
- if (localDim.frameDepth <= 24)
- draw_spans24(y, sx, ex);
- else
- #endif
- #ifdef DRIVER_32BIT
- #endif
- ;
- }
- }
- #else
- /* iterate over all spans and draw */
- #ifdef DRIVER_8BIT
- if (localDim.frameDepth <= 8)
- if (displayType == DISPLAY_TEXTURED)
- draw_spans8(y, ey);
- else if (displayType == DISPLAY_FLAT)
- draw_spans8flat(y, ey);
- else if (displayType == DISPLAY_WIRE)
- draw_spans8wire(y, ey);
- else
- #endif
- #ifdef DRIVER_16BIT
- if (localDim.frameDepth <= 16)
- draw_spans16(y, ey);
- else
- #endif
- #ifdef DRIVER_24BIT
- if (localDim.frameDepth <= 24)
- draw_spans24(y, ey);
- else
- #endif
- #ifdef DRIVER_32BIT
- #endif
- ;
- #endif
- }
-
- void draw_face(__memBase, int face)
- {
- int n = bspMem->shared.quake1.dfaces[face].numedges;
- int se = bspMem->shared.quake1.dfaces[face].firstedge;
- int i, edge, codes_or = 0, codes_and = 0xff;
- point_3d **vlist;
-
- for (i = 0; i < n; ++i) {
- edge = bspMem->shared.quake1.dsurfedges[se + i];
-
- if (edge < 0)
- transform_point(&defaultPoints[i], (vec_t *) & bspMem->shared.quake1.dvertexes[bspMem->shared.quake1.dedges[-edge].v[1]].point);
- else
- transform_point(&defaultPoints[i], (vec_t *) & bspMem->shared.quake1.dvertexes[bspMem->shared.quake1.dedges[edge].v[0]].point);
-
- codes_or |= defaultPoints[i].ccodes;
- codes_and &= defaultPoints[i].ccodes;
- }
-
- if (codes_and)
- return;
- if (codes_or) /* poly crosses frustrum, so clip it */
- n = clip_poly(n, defaultVList, codes_or, &vlist);
- else
- vlist = defaultVList;
-
- /*
- * with this texChange-technique it is possible for example
- * to let light render the bsp-tree, then light marks the
- * last processed face as changed and render the tree again
- * and voila, everything is unchanged but the new lightface
- */
- if (n) {
- struct texture *Text;
-
- Text = GetCache(bspMem, face);
-
- if ((textureMip = compute_mip_level(bspMem, face)) != Text->lastMip) /* if the mipmap changes, the tex and it lights changes too */
- Text->texChanged = TRUE;
-
- GetTMap(bspMem, Text, textureMip); /* GetTMap must have the capability to set texChange */
- compute_texture_gradients(bspMem, Text, textureMip);
- draw_poly(n, vlist);
-
- Text->lastMip = textureMip; /* set last mip here, perhaps GetTMap should use the old value */
-
- /*
- * should we free the whole face if it is an ANIM_MIPMAP?
- * perhaps the sizes etc. changes ...
- */
- }
- }
-